package com.kk.xhr.admin.biz.impl;

import com.kk.xhr.admin.biz.IAppraiseBizService;
import com.kk.xhr.admin.controller.request.AppraiseAddRequest;
import com.kk.xhr.admin.controller.request.AppraiseModifyRequest;
import com.kk.xhr.admin.controller.request.AppraiseQueryRequest;
import com.kk.xhr.admin.controller.vo.AppraiseVO;
import com.kk.xhr.common.pojo.AppraiseResultEnum;
import com.kk.xhr.model.dto.AppraiseDTO;
import com.kk.xhr.model.dto.AppraiseQueryRequestDTO;
import com.kk.xhr.model.dto.PageDto;
import com.kk.xhr.model.service.IAppraiseService;
import com.kk.xhr.model.service.IDepartmentService;
import com.kk.xhr.model.service.INotificationService;
import com.kk.xhr.model.service.IUserService;
import com.kk.xhr.util.DateUtil;
import com.kk.xhr.web.vo.PageVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 考评biz服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/7
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
public class AppraiseBizServiceImpl implements IAppraiseBizService {
    private final IAppraiseService appraiseService;
    private final IUserService userService;
    private final IDepartmentService departmentService;
    private final INotificationService notificationService;

    /**
     * {@inheritDoc}
     */
    @Override
    public PageVO<AppraiseVO> queryPage(AppraiseQueryRequest request) {
        PageDto<AppraiseDTO> dtos = appraiseService.queryPage(AppraiseQueryRequestDTO.builder()
            .userId(request.getUserId())
            .result(request.getResult())
            .status(request.getStatus())
            .limit(request.getLimit())
            .offset(request.getOffset())
            .build());
        return PageVO.fromDTO(dtos, this::generateVO);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<AppraiseVO> queryMine(Long userId) {
        return appraiseService.queryByUserId(userId)
            .stream()
            .map(this::generateVO)
            .collect(Collectors.toList());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<AppraiseVO> queryMemberAppraise(Long userId) {
        List<Long> departmentIds = departmentService.queryByUserId(userId);
        Set<Long> ids = userService.queryByDepartmentIds(departmentIds)
            .stream().filter(id -> !id.equals(userId))
            .collect(Collectors.toSet());
        return appraiseService.queryNotActive(ids)
            .stream()
            .map(this::generateVO)
            .collect(Collectors.toList());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(AppraiseAddRequest request) {
        boolean result = appraiseService.add(request.getUserIds(), AppraiseDTO.builder()
            .appraiseDate(DateUtil.validTime(request.getAppraiseDate()))
            .content(request.getContent())
            .remark(request.getRemark())
            .result(AppraiseResultEnum.OTHER)
            .build());
        if (result) {
            String content = "您有新的考评, 请前往我的考评查看";
            notificationService.batchAdd(request.getUserIds(), content);
        }
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean modify(Long id, AppraiseModifyRequest request) {
        return appraiseService.modify(AppraiseDTO.builder()
            .id(request.getId())
            .appraiseDate(DateUtil.validTime(request.getAppraiseDate()))
            .content(request.getContent())
            .remark(request.getRemark())
            .result(request.getResult())
            .build());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean modifyStatus(Long id, AppraiseResultEnum status) {
        if (null == status) {
            return false;
        }
        return appraiseService.modifyStatus(id, status);
    }

    /**
     * AppraiseVO生成器
     *
     * @param dto AppraiseDTO
     * @return AppraiseVO
     */
    private AppraiseVO generateVO(AppraiseDTO dto) {
        return AppraiseVO.builder()
            .id(dto.getId())
            .name(userService.queryName(dto.getUserId()))
            .userId(dto.getUserId())
            .appraiseDate(dto.getAppraiseDate())
            .content(dto.getContent())
            .remark(dto.getRemark())
            .result(dto.getResult())
            .status(dto.getStatus())
            .build();
    }
}
